package com.example.androidautoproject.service

import android.content.Context
import com.example.androidautoproject.utils.AdParam
import com.example.androidautoproject.utils.ScreenshotUtil
import fi.iki.elonen.NanoHTTPD
import fi.iki.elonen.NanoHTTPD.Response.Status
import org.json.JSONObject

class AndroidHttpServer(port:Int, private val context: Context):NanoHTTPD(port) {
    private var isProcessingScreenshot = false
    private var screenhotUri: String? = ""
    private val TAG = "ServerProject"

    data class ResponseData(
        val status:String = "",
        val screenshot:String = ""
    )

    private fun getMimeType(path: String):String{
        return when{
            path.endsWith(".js") -> "text/javascript"
            path.endsWith(".css") -> "text/css"
            path.endsWith(".png") -> "image/png"
            path.endsWith(".jpg") || path.endsWith(".jpeg") -> "image/jpeg"
            path.endsWith(".svg") -> "image/svg+xml"
            else -> "text/plain"
        }
    }
    private fun serveStaticResource(path: String, contentType: String?=null): Response{
        return try{
            val assetPath = "www/$path"
            val inputStream = context.assets.open(assetPath)
            val mimeType = contentType?: getMimeType(assetPath)
            var response = newFixedLengthResponse(Status.OK, mimeType, inputStream, inputStream.available().toLong())
            response.addHeader("Cache-Control", "no-cache")
            response
        } catch (e: Exception){
            newFixedLengthResponse(Status.NOT_FOUND, "text/plain", "File not found")
        }
    }
    private fun serveTreeData():Response{
        var service = AssistsToolCore()
        if(service != null){
            try{
                val json = service.getNodeTreeAsJson()
                return newFixedLengthResponse(Status.OK, "application/json", json.toString())
            }catch (e:Exception){
                return newFixedLengthResponse(Status.INTERNAL_ERROR, "text/plain", "Error: ${e.message}")
            }
        }else {
            return newFixedLengthResponse(Status.SERVICE_UNAVAILABLE, "text/plain", "Accessibility service not running")
        }
    }

    private fun clickTreeData():Response{
        var service = AssistsToolCore()
        if(service != null){
            try{
                val json = service.getClickNodesAsJson()
                return newFixedLengthResponse(Status.OK, "application/json", json.toString())
            }catch (e:Exception){
                return newFixedLengthResponse(Status.INTERNAL_ERROR, "text/plain", "Error: ${e.message}")
            }
        }else {
            return newFixedLengthResponse(Status.SERVICE_UNAVAILABLE, "text/plain", "Accessibility service not running")
        }
    }

    private fun imagesTreeData():Response{
        var service = AssistsToolCore()
        if(service != null){
            try{
                val json = service.getImageNodesAsJson()
                return newFixedLengthResponse(Status.OK, "application/json", json.toString())
            }catch (e:Exception){
                return newFixedLengthResponse(Status.INTERNAL_ERROR, "text/plain", "Error: ${e.message}")
            }
        }else {
            return newFixedLengthResponse(Status.SERVICE_UNAVAILABLE, "text/plain", "Accessibility service not running")
        }
    }

    private fun textTreeData():Response{
        var service = AssistsToolCore()
        if(service != null){
            try{
                val json = service.getTextNodesAsJson()
                return newFixedLengthResponse(Status.OK, "application/json", json.toString())
            }catch (e:Exception){
                return newFixedLengthResponse(Status.INTERNAL_ERROR, "text/plain", "Error: ${e.message}")
            }
        }else {
            return newFixedLengthResponse(Status.SERVICE_UNAVAILABLE, "text/plain", "Accessibility service not running")
        }
    }

    override fun serve(session: IHTTPSession): Response {
        var path = session.uri
        var method = session.method
        return when{
            path == "/" ->serveStaticResource("index.html", "text/html")
            path == "/auto_tools_index" ->serveStaticResource("auto_tools_index.html", "text/html")
            path == "/tree" -> serveTreeData()
            path == "/clickTree" -> clickTreeData()
            path == "/imagesTree" -> imagesTreeData()
            path == "/textTree" -> textTreeData()
            path.startsWith("/static/") -> serveStaticResource(path.substring(8))
            path == "/screenshot" -> handleScreenshotRequest(session)
            path == "/screenshotNew" -> handleScreenshotRequestNew(session)
            path == "/node/image" -> handleNodeImageRequest(session)
            path == "/nodeByText" -> handleNodeByText(session)
            path == "/getPackageNameAndClassName" -> handlePackageNameAndClassName(session)
            else -> newFixedLengthResponse(Status.NOT_FOUND,"text/plain", "404 Not Found")
        }
    }

    fun handlePackageNameAndClassName(session: IHTTPSession):Response{
        var json = JSONObject()
        json.put("packageName", AdParam.packageName)
        json.put("className", AdParam.className)
        json.put("packageName1", AdParam.packageName1)
        json.put("className1", AdParam.className1)
        return newFixedLengthResponse(Status.OK, "application/json", json.toString())
    }

    fun handleNodeByText(session: IHTTPSession):Response{
        val service = MainService.instance
        if (service == null) {
            return newFixedLengthResponse(Status.INTERNAL_ERROR, "application/json",
                "{\"success\": false, \"error\": \"Service not available\"}")
        }
        val text = session.parms["text"]
        var notes = service.findNodesByTextAsJson(text!!)
        return newFixedLengthResponse(Status.OK, "application/json", notes.toString())
    }


    fun handleScreenshotRequest(session: IHTTPSession): Response{
        val service = MainService.instance
        if (service == null) {
            return newFixedLengthResponse(Status.INTERNAL_ERROR, "application/json",
                "{\"success\": false, \"error\": \"Service not available\"}")
        }
        // 在后台线程处理截图
        Thread {
            service.takeScreenshot { screenshotPath ->
                screenhotUri = ScreenshotUtil.filePathToBase64(screenshotPath !!)
            }
        }.start()
        Thread.sleep(3000)
        val json = JSONObject().apply {
            put("status", "success")
            put("screenshot", screenhotUri)
        }
        return newFixedLengthResponse(Status.OK, "application/json", json.toString())
    }

    fun handleScreenshotRequestNew(session: IHTTPSession): Response{
        val json = JSONObject().apply {
            put("status", "success")
            put("screenshot", ScreenshotUtil.base64)
        }
        return newFixedLengthResponse(Status.OK, "application/json", json.toString())
    }

    fun handleNodeImageRequest(session: IHTTPSession): Response{
        val nodeId = session.parms["nodeId"]
        val left = session.parms["left"]?.toIntOrNull()
        val top = session.parms["top"]?.toIntOrNull()
        val right = session.parms["right"]?.toIntOrNull()
        val bottom = session.parms["bottom"]?.toIntOrNull()
        val service = MainService.instance
        if (service == null) {
            return newFixedLengthResponse(Status.INTERNAL_ERROR, "application/json",
                "{\"success\": false, \"error\": \"Service not available\"}")
        }
        // 在后台线程处理截图
//        Thread {
//            service.takeScreenshot { screenshotPath ->
//                screenhotUri = screenshotPath
//            }
//        }.start()
//        Thread.sleep(4000)
        var nodeScreenhotUri = ScreenshotUtil.cropNodeByPath(ScreenshotUtil.screenshotPath !!, left!!, top!!, right!!, bottom!!)
        val json = JSONObject().apply {
            put("status", "success")
            put("screenshot", nodeScreenhotUri)
        }
        return newFixedLengthResponse(Status.OK, "application/json", json.toString())
    }
}